import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_draw/p18/particle.dart';
import 'package:flutter_draw/p18/particle_manage.dart';

class World extends StatefulWidget {
  const World({super.key});

  @override
  State<World> createState() => _WorldsState();
}

/// 创建一个世界的组件 World ，世界会提供一个持续流动的时间来渲染世界中的元素，
/// 这里通过 AnimationController 的 repeat 来让动画不停运动来模拟恒定的时间流，
/// 注意动画器的 Duration 是无所谓的，我们并不需要动画器的值。
/// 动画器每次刷新时会执行 ParticleManage#tick 所以之后的要点在于 tick 方法中对粒子属性的变化。
/// 另外在点击时通过 theWorld 的方法来停止/继续时间的流动。
class _WorldsState extends State<World> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  ParticleManage pm = ParticleManage(size: Size.zero);
  Random random = Random();
  late Timer timer;

  @override
  void initState() {
    super.initState();
    initParticleManage();
    // 定义计时器
    /// 每隔一秒向粒子管理器中添加一个随机粒子，如下所示。
    /// 可以通过 Timer 来执行一个周期是 1s 定时任务，每次执行时向粒子管理器中添加一个粒子即可。
    timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      // 如果粒子数大于20，停止计时器
      if (pm.particles.length > 20) {
        timer.cancel();
      }
      // 添加随机粒子
      pm.addParticle(Particle(
          color: randomRGB(),
          size: 5 + 4 * random.nextDouble(),
          vx: 3 * random.nextDouble() * pow(-1, random.nextInt(20)),
          vy: 3 * random.nextDouble() * pow(-1, random.nextInt(20)),
          ay: 0.1,
          x: 150,
          y: 100));
    });
    _controller =
        AnimationController(vsync: this, duration: const Duration(seconds: 1))
          ..addListener(pm.tick)
          ..repeat();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void initParticleManage() {
    pm.size = const Size(300, 200);
    // 水平匀速直线运动
    Particle particle1 =
        Particle(x: 0, y: 0, vx: 2, color: Colors.blue, size: 8);
    // 倾斜匀速直线运动
    Particle particle2 =
        Particle(x: 0, y: 0, vx: 1.2, vy: 2, color: Colors.blue, size: 8);
    // 加速度
    Particle particle3 = Particle(
        x: 0, y: 0, vx: 3, vy: 0, ay: 0.05, color: Colors.blue, size: 8);
    pm.particles.add(particle1);
    pm.particles.add(particle2);
    pm.particles.add(particle3);

    for (var i = 0; i < 30; i++) {
      pm.particles.add(Particle(
          color: randomRGB(),
          size: 5 + 4 * random.nextDouble(),
          vx: 3 * random.nextDouble() * pow(-1, random.nextInt(20)),
          vy: 3 * random.nextDouble() * pow(-1, random.nextInt(20)),
          ay: 0.1,
          x: 150,
          y: 100));
    }
  }

  // 获取随机色
  Color randomRGB({
    int limitR = 0,
    int limitG = 0,
    int limitB = 0,
  }) {
    var r = limitR + random.nextInt(256 - limitR); //红值
    var g = limitG + random.nextInt(256 - limitG); //绿值
    var b = limitB + random.nextInt(256 - limitB); //蓝值
    return Color.fromARGB(255, r, g, b); //生成argb模式的颜色
  }

  void theWorld() {
    if (_controller.isAnimating) {
      _controller.stop();
    } else {
      _controller.repeat();
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: theWorld,
      child: CustomPaint(
        size: pm.size,
        painter: WorldRender(manage: pm),
      ),
    );
  }
}

class WorldRender extends CustomPainter {
  final ParticleManage manage;

  WorldRender({required this.manage}) : super(repaint: manage);

  Paint fillPaint = Paint();
  Paint strokePaint = Paint()
    ..strokeWidth = 0.5
    ..style = PaintingStyle.stroke;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawRect(Offset.zero & size, strokePaint);
    for (var particle in manage.particles) {
      drawParticle(canvas, particle);
    }
  }

  void drawParticle(Canvas canvas, Particle particle) {
    fillPaint.color = particle.color;
    canvas.drawCircle(Offset(particle.x, particle.y), particle.size, fillPaint);
  }

  @override
  bool shouldRepaint(covariant WorldRender oldDelegate) =>
      oldDelegate.manage != manage;
}
